home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 5 / Amiga Tools 5.iso / tools / developer-tools / amos-tools / optimisation_tips.txt < prev    next >
Encoding:
Text File  |  1996-02-25  |  11.3 KB  |  403 lines

  1.  
  2. AMOS Code Optimisation Tips
  3. ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. Aminet - dev/amos/OptimiseTips.lha
  5.  
  6. Compiled by :
  7.  
  8.    Ben Wyatt       bwyatt@paston.co.uk
  9.  
  10. Contributors :
  11.  
  12.    Ben Wyatt       bwyatt@paston.co.uk
  13.    Paul Hickman    ph@doc.ic.ac.uk
  14.    Tim Lewis       T.Lewis@bton.ac.uk
  15.    Petri Hakkinen  mystic@tlti.tokem.fi
  16.    Mark de Jong    JP.de.Jong@inter.nl.net
  17.    Paul Heald      u5o83@cc.keele.ac.uk
  18.  
  19. Here are a few optimisation tips for those of you trying to squeeze that
  20. little bit more speed out of code. With the follow examples, the speed
  21. increase may not be noticable, but they will all make it that little bit
  22. faster.
  23.  
  24. Note: Some of these speed increases only work when compiled, mainly with
  25. the AMOSPro Compiler.
  26.  
  27. 1. Don't use Sgn(n), use n<0 and n>0 instead.
  28.  
  29.    Eg.
  30.       Don't use :
  31.          If Sgn(n)=-1 Then blah blah
  32.          If Sgn(n)=1 Then blah de blah
  33.       Use this instead :
  34.          If n<0 Then blah blah
  35.          If n>0 Then blah de blah
  36.  
  37. 2. For your most used array of 8 (or less) elements, use Dreg() instead of
  38.    it (it can still hold the same range of values). Note: The Dreg() array
  39.    isn't actually using the data registers; it's an AMOS internal data
  40.    structure. However, it's still faster than a standard array.
  41.  
  42.    Eg.
  43.       Don't use :
  44.          Dim n(7)
  45.          For a=0 to 7:Print n(a):Next a
  46.       Use this instead :
  47.          For a=0 To 7:Print Dreg(a):Next a
  48.  
  49. 3. Use Abs(n)<v instead of n>-v and n<v.
  50.  
  51.    Eg.
  52.       Don't use :
  53.          If n>-5 and n<5 Then blah
  54.       Use this instead :
  55.          If Abs(n)<5 Then blah
  56.  
  57. 4. Whenever possible use powers of 2 when multiplying or dividing. The
  58.    AMOSPro Compiler will automatically optimise these to lsl and lsr.
  59.    DON'T use the lsl or lsr commands in extensions, as they are over
  60.    TWICE as slow!
  61.  
  62.    Eg.
  63.       Don't use :
  64.          n=a*30
  65.       Use this instead (if suitable) :
  66.          n=a*32
  67.  
  68.    As well as this, you can also do :
  69.  
  70.       n=x*160 -> n=x*(128+32) -> n=x*128+x*32 (tadaa)
  71.  
  72.       Also n=x*192 -> n=x*128+x*64 etc.
  73.  
  74. 5. Predefine as much as possible. Especially useful for Sin and Cos etc.
  75.  
  76.    Eg.
  77.       Don't use :
  78.          Repeat
  79.             If Sqr(x*x+y*y)=10 Then blah blah blah
  80.          Until Something
  81.       Use this instead :
  82.          xmax=Maximum value of x : ymax=Maximum value of y
  83.          Dim QUICKSQR(xmax,ymax)
  84.          For x=0 to xmax
  85.             For y=0 to ymax
  86.                QUICKSQR(x,y)=SQR(x*x+y*y)
  87.             Next y
  88.          Next x
  89.          Repeat
  90.             If QUICKSQR(Abs(x),Abs(y))=10 Then blah blah blah
  91.          Until Something
  92.  
  93. 6. Get yourself a fast extension, such as AMCAF or Turbo Plus. This will
  94.    only speed things up where an extension command replaces an internal
  95.    command with a faster one - Easylife and AMCAF will do this for many
  96.    string operations.
  97.  
  98.    Eg.
  99.       Don't use :
  100.          Plot x,y,c
  101.       Use this instead :
  102.          Turbo Plot x,y,c (for AMCAF)
  103.       or F Plot x,y,c (for Turbo Plus)
  104.  
  105. 7. Use < and > instead of <= and >= whenever possible. They are slightly
  106.    faster. Strange, but true.
  107.  
  108.    Eg.
  109.       Don't use :
  110.          If n<=10 Then blah
  111.       Use this instead :
  112.          If n<11 Then blah
  113.  
  114. 8. Don't do stuff like If n=True, If n=False, or If n<>0. Also, using =False
  115.    instead of =0 is faster.
  116.  
  117.    Eg.
  118.       Don't use :
  119.          If a=True or b=False or c<>0 Then blah blah
  120.       Use this instead :
  121.          If a or Not(b) or c Then blah blah
  122.  
  123.    But ONLY do this if you are sure b is a boolean value. "Not" simply
  124.    bitflips an integer so Not -1 is 0, but Not 2 is $FFFFFFFE.
  125.  
  126. 9. Never use floating points. Use integers multiplied by a power of 2. You
  127.    can actually decide what sort of precision you want in your decimal places
  128.    and then multiply them out. For example, if you decide on about 2 point
  129.    accuracy, you can multiply all your values by 128 (2^7, close enough to
  130.    100) and then do the calculations. When you have the results simply divide
  131.    by 128 to get the required result.
  132.  
  133.    Eg.
  134.       Don't use :
  135.          x#=x#*1.5
  136.          Plot x#,100
  137.       Use this instead :
  138.          x=x*(3*128) : Rem Same as x=x*(1.5*256)
  139.                        Rem 3*128 is calculated at compilation time
  140.          Plot X/256,100
  141.  
  142. 10. Use assembler procedures for inner loops.
  143.  
  144. 11. Use "Copper Off" to disable the screen while doing intense communication.
  145.     The copper then stops stealing clock cycles from the processor (Unlke
  146.     Multi No and such instructions, this really does work). Use "Copper On"
  147.     to re-enable the normal system.
  148.  
  149. 12. Move invarient statement outside loops (Standard optimising compiler
  150.     stuff).
  151.  
  152.     Eg.
  153.        If you have something like this :
  154.           Repeat
  155.              If x<a*20 Then do something groovy
  156.           Until something
  157.        If the rest of the loop does not modify a, this can become :
  158.           temp=a*20
  159.           Repeat
  160.              If x<temp Then do something groovy
  161.           Until something
  162.  
  163. 13. Use global variables to return parameters from procedures, rather than
  164.     Param.
  165.  
  166. 14. Use Cls col,x1,y1 To x2,y2 instead of Bar x1,y1 To x2,y2.
  167.     Note : Use R Bar in Turbo instead if possible.
  168.  
  169. 15. Use Polyline to draw boxes instead of Box.
  170.     Note : Use R Box in Turbo instead if possible.
  171.  
  172.     Eg.
  173.        Don't use :
  174.           Box 10,10 To 10,10
  175.        Use this instead :
  176.           Polyline 10,10 To 20,10 To 20,20 To 10,20
  177.  
  178. 16. Use single dimensional arrays instead of two dimensional ones if
  179.     possible.
  180.  
  181.     Eg.
  182.        Don't use :
  183.           Dim A(2,100)
  184.        Use this instead :
  185.           Dim A0(100),A1(100),A2(100)
  186.  
  187. 17. Use N=N+A instead of using Inc, Dec or Add. Although the manual claims
  188.     they are faster, when using the AMOSPro Compiler, they actually turn
  189.     out slightly slower.
  190.  
  191.     Eg.
  192.        Don't use :
  193.           Inc a : Dec b : Add c,10
  194.        Use this instead :
  195.           a=a+1 : b=b-1 : c=c+10
  196.  
  197.     Note : Although Add is slower in it's short form, the full version
  198.     with the base To top part is faster than the equivilant code.
  199.  
  200. 18. Use a Repeat / Until loop instead of a For / Next loop.
  201.  
  202.     Eg.
  203.        Don't use :
  204.           For n=0 to 10
  205.              (code)
  206.           Next n
  207.        Use this instead :
  208.           n=0
  209.           Repeat
  210.              (code)
  211.              n=n+1
  212.           Until n=11 : Rem MUST be one more than with the original For
  213.  
  214. 19. Use Peek(Varptr(a$)+x-1) instead of Asc(Mid$(a$,x,1)) and
  215.     Poke Varptr(a$)+x-1,Asc(b$) instead of Mid$(a$,x,1)=b$.
  216.  
  217.     Eg.
  218.        Don't use :
  219.           A=Asc(Mid$(a$,3,1))
  220.           Mid$(a$,6,1)=b$
  221.        Use this instead :
  222.           A=Peek(Varptr(a$)+2)
  223.           Poke Varptr(a$)+5,Asc(b$) : Rem Asc(b$) could be predefined
  224.  
  225.     Note : This is just under three times as fast!
  226.  
  227. 20. Use Fill to clear an array to a certain value, rather than the
  228.     equivilant For / Next loop.
  229.  
  230.     Eg.
  231.        Don't use :
  232.           For n=0 to 1000
  233.              A(n)=27
  234.           Next n
  235.        Use this instead :
  236.           Fill Varptr(A(0)) To Varptr(A(1000)),27
  237.  
  238. 21. Use "If condition Then code" instead of "If condition : code : End If",
  239.     if the code is short.
  240.  
  241.     Eg.
  242.        Don't use :
  243.           If a=2
  244.              la-de-da
  245.           End If
  246.        Use this instead :
  247.           If a=2 Then la-de-da
  248.  
  249. 22. Use subroutines instead of procedures. Although they're messier, they are
  250.     several times faster!
  251.  
  252.     Eg.
  253.        Don't use :
  254.           _SOMETHING
  255.           Procedure _SOMETHING
  256.              Code
  257.           End Proc
  258.        Use this instead :
  259.           Gosub _SOMETHING
  260.           _SOMETHING:
  261.              Code
  262.           Return
  263.  
  264. 23. This routine is for making the string 1 character shorter. It may be
  265.     helpful in an program to replace the input command. But the question
  266.     is if you need that speed in such a routine ;-)
  267.  
  268.     Eg.
  269.        Don't use :
  270.           S$=Space$(1000)
  271.           For X=1 To 1000
  272.              S$=Left$(S$,Len(S$)-1)
  273.           Next X
  274.        Use this instead :
  275.           S$=Space$(1000)
  276.           POS=Varptr(S$) : Rem Put this statement inside the loop if you
  277.                            Rem do any standard string operations.
  278.           For X=1 To 1000
  279.              Doke POS-2,Deek(POS)-1
  280.           Next X
  281.  
  282. 24. Don't use Start(BANK), Screen Width or Screen Height in a routine that
  283.     must be fast. In fact, use any AMOS variable that won't change in
  284.     the loop.
  285.  
  286.     Eg.
  287.        Don't use :
  288.           For X=1 To 10000
  289.              PE=Peek(Start(10)+X)
  290.           Next X
  291.        Use this instead :
  292.           ST=Start(BANK)
  293.           For X=1 To 10000
  294.              PE=Peek(ST+X)
  295.           Next X
  296.  
  297. 25. Don't use Chr$(code) in routines but replace them with a string.
  298.  
  299.     Eg.
  300.        Don't use :
  301.           I=Instr(ST$,Chr$(0))
  302.        Use this instead :
  303.           C0$=Chr$(0)      : Rem at the beginning of your prog
  304.           I=Instr(ST$,C0$) : Rem in the routine
  305.  
  306. 26. A quasi-optimisation: Use "n=Free" at points where you don't care about
  307.     the speed, to reduce the chances of the AMOS string garbage collector
  308.     being called when you do care about the speed. This will only have
  309.     an effect when strings are used in the routine.
  310.  
  311. 27. Don't use parameters in Def Fns. As functions are local to procedures,
  312.     any variables used, will be known in the function.
  313.  
  314.     Eg.
  315.        Don't use :
  316.           Def Fn C(x,y)=(x*y*y+x) MOD 16
  317.           For x=0 To 10
  318.              For y=0 To 10
  319.                 Plot x,y,Fn C(x,y)
  320.              Next y
  321.           Next x
  322.        Use this instead :
  323.           Def Fn C=(x*y*y+x) MOD 16
  324.           For x=0 To 10
  325.              For y=0 To 10
  326.                 Plot x,y,Fn C
  327.              Next y
  328.           Next x
  329.  
  330. 28. Use as few brackets in equations and If structures as possible.
  331.  
  332.     Eg.
  333.        Don't use :
  334.           A=(B*C)-(D*E)-(F+G)
  335.           If (A=2) or (B=100) Then blah blah
  336.        Use this instead :
  337.           A=B*C-D*E-F-G
  338.           If A=2 or B=100 Then blah blah
  339.  
  340. 29. Use the value of expressions, rather than testing what they mean.
  341.  
  342.     Eg.
  343.        Don't use :
  344.           If Jup(1)
  345.              Y=Y-1
  346.           End If
  347.           If Jdown(1)
  348.              Y=Y+1
  349.           End If
  350.        Use this instead :
  351.           Y=Y+Jup(1)-Jdown(1)
  352.  
  353.     Remember : if it is true, -1 is returned, otherwise 0 is returned.
  354.  
  355.     The Turbo (Plus) extension has a useful command called "Texp" which
  356.     returns specified values for True and False.
  357.  
  358. 30. The fastest way to display a map, using a few of the above tips :
  359.  
  360.        ' This is the slow way, that I've seen in multiple sources of games
  361.        For Y=0 To FHV
  362.           For X=0 To FWV
  363.              Paste Icon 16+X*16,16+Y*16,Peek((FPOSY+Y)*FW+Start(BLS1)+FPOSX)+1
  364.           Next X
  365.        Next Y
  366.  
  367.        ' Now my quick version... Note that the start(bank)
  368.        ' is placed in front of the routine.
  369.        ' FHV   = Field Height View
  370.        ' FHV   = Field Width  View
  371.        ' FPOSX = Field POSition X (Where the player is looking in the map)
  372.        ' FPOSY = Field POSition Y
  373.        POS=Start(BLS1)+FPOSX
  374.        For Y=0 To FHV
  375.           MPY=(FPOSY+Y)*FW+POS
  376.           SPY=16+Y*16
  377.           For X=0 To FWV
  378.              ' Using a Turbo Plus extension command
  379.              F Paste Icon 16+X*16,SPY,Peek(MPY+X)+1
  380.           Next X
  381.        Next Y
  382.  
  383.  
  384.  
  385. Try various ways of writing code to see if you can find the quickest.
  386. Something like this is a nice way :
  387.  
  388.    Timer=0
  389.    For n=0 To 10000
  390.       Unoptimised code
  391.    Next n
  392.    Print "Time for unoptimised code :";Timer
  393.  
  394.    Timer=0
  395.    For n=0 To 10000
  396.       Optimised code
  397.    Next n
  398.    Print "Time for optimised code :";Timer
  399.  
  400. If you find any general purpose tips, send them to me (at bwyatt@paston.co.uk)
  401. and I'll add them to the list!
  402.  
  403.